package com.dome.gateway.rule;

import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.dome.auth.UserContextHolder;
import com.google.common.base.Optional;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: hz
 * @time: 2021/5/3 16:05
 */
public class GrayMetadataRule extends ZoneAvoidanceRule {
    public static final String META_DATA_KEY_VERSION = "version";

    private static final Logger logger = LoggerFactory.getLogger(GrayMetadataRule.class);

    @Override
    public Server choose(Object key) {

        List<Server> serverList = this.getPredicate().getEligibleServers(this.getLoadBalancer().getAllServers(), key);
        if (CollectionUtils.isEmpty(serverList)) {
            return null;
        }

        String hystrixVer = UserContextHolder.getInstance().getVersion();
        logger.debug("======>GrayMetadataRule:  hystrixVer:{}", hystrixVer);
        List<Server> noMetaServerList = new ArrayList<>();
        if(StringUtils.isNotEmpty(hystrixVer)) {
            //如果头部有传输版本号.就走筛选的逻辑
            for (Server server : serverList) {
//				if(server instanceof )
                Map<String, String> metadata = ((NacosServer) server).getMetadata();

                // version策略 如果 eureka.instance.metadata-map有配值version
                String metaVersion = metadata.get(META_DATA_KEY_VERSION);
                if (StringUtils.isNotEmpty(metaVersion)) {
                    if (metaVersion.equals(hystrixVer)) {
                        noMetaServerList.add(server);
                    }
                } else {
                    noMetaServerList.add(server);
                }
            }
            if (!noMetaServerList.isEmpty()) {
                return originChoose(noMetaServerList, key);
            }
        } else {
            //如果没有版本头.走原来负载均衡逻辑
            return super.choose(key);
        }





        return null;
    }

    private Server originChoose(List<Server> noMetaServerList, Object key) {
        Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(noMetaServerList, key);
        if (server.isPresent()) {
            return server.get();
        } else {
            return null;
        }
    }
}
